package com.example.core.aop;

import com.example.core.annotation.DDS;
import com.example.core.context.CommonContext;
import com.example.core.context.CustomContext;
import com.example.core.datasource.DynamicDataSourceUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

@Aspect
@Component
public class DynamicDataSourceAop {

    private Logger logger = LoggerFactory.getLogger(DynamicDataSourceAop.class);

    @Around(value = "cutMethod()")
    public Object switchDataSourceAOP(ProceedingJoinPoint joinPoint) throws Throwable {
        return switchDataSource(joinPoint);
    }

    @Pointcut("@annotation(com.example.core.annotation.DDS)")
    private void cutMethod() {

    }

    private Object switchDataSource(ProceedingJoinPoint joinPoint) throws Throwable {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        CommonContext context = CommonContext.getContext();
        CustomContext customContext = context.getCustomContext();
        String app = customContext.getApp();
        if (method != null) {
            DDS annoObj = method.getAnnotation(DDS.class);
            String value = annoObj.value();
            customContext.setDataSourceApp(value);
            logger.debug("aop method:{},switch dataSource: {}", method.getName(), value);
        }
        Object proceed = joinPoint.proceed();
        if (StringUtils.isEmpty(app)) {
            app = DynamicDataSourceUtil.getDefaultSource();
        }
        customContext.setDataSourceApp(app);
        logger.debug("aop method:{},switch back dataSource: {}", method.getName(), app);
        return proceed;
    }

}
